home *** CD-ROM | disk | FTP | other *** search
-
- (c) 1990 S.Hawtin.
- Permission is granted to copy this file and make provided that:
- 1) Neither are used for commercial gain
- 2) This notice is included in all copies
- 3) Altered copies are marked as such.
- 4) Each copy of make is accompanied by a copy of this file.
-
- No liability is accepted for the contents of the file.
-
- make.doc within make
-
- MAKE
- make [-fmakefile][-?][target]
-
- Maintain an up-to-date version of a program. The options have the
- following meanings
-
- -f<makefile>
-
- Take the description from the file <makefile> rather than "Makefile".
-
- -?
-
- Print out the commands that would be executed but do not perform them.
-
- target
-
- Construct the file <target> rather than the first item in the makefile.
- The special target "$*.blink" will cause the program to create a file
- that can be used by the "Blink" program to link the object files together.
-
- The make command keeps programs up to date, it does this by reading a
- file that describes how to construct a target program and executing all
- the commands required to update the program.
-
- When using 'C' and other compiled languages it is normal to divide the
- source code for a program into many files, this allows you to split the
- code into logical chunks. Most compiled languages allow you to recompile
- each source file independently to produce an "object" file, the user then
- combines all the object files to produce the actual program with a
- "linker". Whenever you alter a source file it must be recompiled and the
- resulting "object" file must be relinked into the executable program, it
- can be difficult to remember which files you have changed since the last
- build and what set of tools need to be run on which programs. The "make"
- program works out which commands need to be executed to bring a program up
- to date and executes them.
-
- An example will explain what the program does, assume you have a program
- called "jim" that combines three source files, "foo.c", "bar.c" and
- "baz.asm". To use "make" in its simplest form you should create a file
- called "Makefile" containing the lines
-
- jim : foo.o bar.o baz.o
- blink with $*.blink
-
- this tells the "make" program that "jim" depends on the object files
- "foo.o", "bar.o" and "baz.o", and that "jim" can be created by the CLI
- command "blink with jim.blink". You must now construct the file
- "jim.blink" that the "blink" command requires, this is done by the CLI
- command
-
- make $*.blink
-
- the "$*" construct will be explained later.
-
- Once the "Makefile" and "jim.blink" files have been created you can use
- the "make" program to construct "jim", just type the command
-
- make
-
- and it will call all the commands to make "jim". Now if you change the
- file "foo.c" and then type the "make" command it will only issue the
- commands required to bring the program up to date, the program will not
- bother to recompile "bar.c" or "baz.asm". The "make" program is clever
- enough to know that "bar.c" needs to be compiled and "baz.asm" needs to
- be assembled program.
-
- So every time you change a set of the source files you just type "make"
- and all the necessary compilations will be done. This is well and good,
- assuming we are only going to edit the ".c" and ".asm" files. If however
- if you change an include file you want "make" to recompile all the 'C'
- source files that include it. We get make to do this by adding some extra
- lines into the "Makefile". If the new "Makefile" contains
-
- jim : foo.o bar.o baz.o
- blink with $*.blink
-
- foo.o: fubar.h foo.h
-
- bar.o : fubar.h
-
- then every time "fubar.h" is altered "make" will recompile both "foo.c"
- and "bar.c". Notice that the three items "jim", "foo.o" and "bar.o" must
- be separated by blank lines. If we now change the file "fubar.h" then the
- "make" command will recompile both "foo.c" and "bar.c".
-
- By default the "make" program always tries to construct the first item
- in the "Makefile", this is why you must put the line
-
- foo.o: fubar.h
-
- after
-
- jim : foo.o bar.o baz.o
-
- if it was put in before then the "make" program would just make "foo.o"
- and not "jim". You can get "make" to construct a particular item by
- telling it which target item you want to update, for example to make
- "bar.o" just type the command
-
- make bar.o
-
- we have already seen this being used when we created the "jim.blink" file.
-
- So, to summarise, each item in the "Makefile" starts with a file name,
- then after the ':' a list of items that this item depends on, the
- following lines, up to the first blank line, tell "make" the commands
- required to construct the item. Each item can appear on the left hand
- side as many times as you want so long as you only specify the commands to
- create it once.
-
- You can of course add comments into the "Makefile", any line that starts
- with a '#' is treated as a comment.
-
- One problem you might come across is having too many dependencies to fit
- on a single line, the '\' character tells "make" that the dependencies are
- continued on the next line, so for example
-
- jim: foo.o \
- bar.o \
- baz.o
- blink with $*.blink
-
- is the same as the original entry for "jim". The '\' character must be
- the last character on the line.
-
- Sometimes you want to "make" an item every time you construct the
- program, for example if you have a file "date.c" that consists of
-
- #include <stdio.h>
-
- print_date()
- {/* Print the date the program was last compiled */
- printf("This version was compiled on %s\n",__DATE__);
- }
-
- then even though the actual text of the source file does not change you
- want to recompile it whenever the program is compiled. You can force
- "make" to always recompile this program by appending the special item
- "always", for example by adding the item
-
- date.o : always
-
- to the Makefile. "always" is considered to be newer than everything
- else. The "__DATE__" macro is an ANSI C extension that returns a string
- containing the compilation date.
-
- Although the "make" program knows how to convert a ".c" program into a
- ".o" program you can override this by adding an item such as
-
- foo.o: foo.c
- NorthC -I:incl/ foo.c
- A68k foo.s
- Delete foo.s
-
- whenever "foo.c" is changed the given commands will be executed to create
- "foo.o" rather than the normal commands.
-
- If you have a preferred way to convert ".c" files into ".o" files you
- could type this in after every ".o" file, however "make" will also allow
- you to define a "default" way to convert between the files, if you add the
- item
-
- .c.o:
- NorthC -I:incl/ $*.c
- A68K $*.s
- Delete $*.s
-
- to the "Makefile" this item tells "make" to construct ".o" files from ".c"
- files by calling the commands
-
- NorthC -I:incl/ $*.c
- A68K $*.s
- Delete $*.s
-
- The sequence "$*" is replaced by the base file name. The base file name
- consists of the name up to the final '.', so for example the base name of
- "jim.2.c" is "jim.2".
-
- "make" will always add some default items to the end of the "Makefile",
- if they do not clash with existing entries, the current default items are
-
- .c.o:
- NorthC -Ot:$*.s $*.c
- A68K -q -g -O$*.o t:$*.s
- Delete t:$*.s
-
- .s.o:
- A68K $*.s
-
- .asm.o:
- A68K $*.asm
-
- this tells the "make" program how to compile 'C' programs and assemble
- ".asm" and ".s" files.
-
- You can use the default mechanism to create files with any extension of
- up to four letters, for example
-
- .uil.uid:
- Delete $*.uid
- Motif:Uil/uil -o $*.uid $*.uil
-
- tells "make" that each time it finds a reference to a file such as
- "jim.uid" it should construct the file with the commands
-
- Delete jim.uid
- Motif:Uil/uil -o jim.uid jim.uil
-
- whenever the "jim.uil" file is altered.
-
- You can split your "Makefile" into multiple files. When you want to
- read a file, for example "make.depends", just include the command
-
- $<make.depends>
-
- in "Makefile". Make will read the file "make.depends" at that point.
-
- If you wish to read a file other than "Makefile" when you call "make"
- add the "-f" option, for example to read the dependencies from "jim.make"
-
- make -fjim.make
-
- will make the first item in the file "jim.make".
-
- If you want to use the "top" optimiser you should add an item
-
- .c.o:
- NorthC -Ot:$*.s $*.c
- top t:$*.s t:$*.s1
- a68k -g -q -O$*.o t:$*.s
- delete t:$*.s t:$*.s1
-
- into your makefiles.
-
-
- How Make Works
-
- You don't actually have to read this bit but it might help if you cannot
- get "make" to do something complicated.
-
- The "make" command works by creating a dependency tree, for example the
- sequence
-
- jim: foo.o bar.o baz.o
- blink with $*.blink
-
- foo.o: fubar.h foo.h
-
- bar.o: fubar.h
-
- will create a dependency tree
-
- jim
- / | \
- / | \
- / | \
- / | \
- foo.o bar.o baz.o
- | \ /
- | fubar.h
- |
- foo.h
-
- "make" then scans this tree to find items that have no create command
- sequence defined. Any item that we have not yet been told how to make
- will either be a source file, for example "foo.h" or we will have to find
- out how to make it from the defaults list. So make will now scan the
- tree, when it comes to "foo.o" it discovers that it has a method for
- creating ".o" files from ".c" files, and a ".c" file exists, so it adds
- the default ".c.o" create method to "foo.o" and adds "foo.c" to its
- dependencies. When it comes to the file "bar.o" because it cannot find
- "bar.c" it looks further down the list of defaults and finds that a
- "bar.asm" file exists. Once the tree has been scanned it looks like
-
- jim
- / | \
- / | \
- / | \
- / | \
- foo.o bar.o baz.o
- / | \ / \ |
- foo.c | fubar.h \ baz.asm
- | \
- foo.h bar.c
-
- "make" then goes over this tree to see if any item is older than one of
- its dependencies, when it finds such an item it adds the commands for
- creating this item to an intermediate file in the "t:" directory.
-
- Once it has gone over the tree it calls the AmigaDOS command "execute"
- to run the created command file, I have to call this function because I
- want "make" to stop as soon as one of the commands fails. I cannot find
- out how to determine the return code of a called program, if anyone out
- there can tell me how to do this please get in touch.
-
- The last thing the program does is to delete the command file it created
- in the "t:" directory.
-